Skip to content

test(integration): add PostgreSQL 14-18 compatibility matrix#150

Merged
opzkit-auto-merge[bot] merged 5 commits into
mainfrom
test/pg-version-matrix
May 7, 2026
Merged

test(integration): add PostgreSQL 14-18 compatibility matrix#150
opzkit-auto-merge[bot] merged 5 commits into
mainfrom
test/pg-version-matrix

Conversation

@peter-svensson

Copy link
Copy Markdown
Member

Summary

Adds a per-version PostgreSQL compatibility test matrix to the integration suite. Five versioned PG instances (14, 15, 16, 17, 18) run side-by-side in the kind cluster; a single Ginkgo test exercises CREATE USER + GRANT + CREATE DATABASE OWNER against each.

Why

Smoke testing during the secrets-backend refactor (PR #135) surfaced two PG-version-specific bugs in the operator's admin-grant path:

  1. GRANT %s TO CURRENT_USER rejected as a special role specifier on Scaleway managed RDB.
  2. PG 16+ changed GRANT defaults to NOINHERIT, NOSET, NOADMIN, so CREATE DATABASE x OWNER y requires the executor to hold SET on y. Vanilla PG 16/17/18 fail with must be able to SET ROLE (42501) without WITH INHERIT TRUE, SET TRUE on the GRANT.

Neither bug reproduces on AWS RDS or Aurora because their event triggers paper over PG 16's stricter defaults. We had no CI signal for vanilla / Scaleway-style providers across the supported version range. This PR closes that gap.

Files

  • test/integration/manifests/postgres-versions.yaml — Deployments + Services for postgres-14 ... postgres-18 in the databases namespace, plus admin-DSN Secrets in the default namespace.
  • test/integration/postgres_versions_test.go — table-driven Ginkgo Describe iterating the five versions, asserting Ready phase and Secrets Manager content per version.
  • test/integration/scripts/setup-cluster.sh — apply the new manifest and wait for all five pods.

Expected CI behaviour

This branch deliberately runs against main without the PR #135 grant fix. The matrix should:

  • ✅ pass on PG 14 and 15 (pre-NOINHERIT/NOSET defaults).
  • ❌ fail on PG 16, 17, 18 with the operator's current GRANT %s TO CURRENT_USER statement.

Once #135 lands on main and this branch is rebased, all five versions will pass. The failure here is the point — it proves the matrix actually catches the regression class that #135 fixes, rather than being a passing rubber stamp.

Cost

  • ~1 GB extra RAM in the runner for five PG pods (Ubuntu runner has 7 GB, fits comfortably).
  • ~30-60s extra CI time (pulls cached, single Database CR per version).

Test plan

@peter-svensson peter-svensson requested a review from argoyle as a code owner May 7, 2026 14:23
@peter-svensson peter-svensson force-pushed the test/pg-version-matrix branch from c3d9c72 to b75ba24 Compare May 7, 2026 14:27
@opzkit-auto-merge opzkit-auto-merge Bot enabled auto-merge (squash) May 7, 2026 14:28
argoyle
argoyle previously approved these changes May 7, 2026

@argoyle argoyle left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔢

Deploy 5 versioned PostgreSQL instances (postgres-14 through
postgres-18) in the kind cluster and run a focused matrix test
exercising the CREATE USER + GRANT + CREATE DATABASE OWNER path
for each version.

PG 16+ tightened GRANT defaults to NOINHERIT, NOSET, NOADMIN.
A regression in the operator's admin-grant statement that omits
WITH INHERIT TRUE, SET TRUE will now fail loudly on PG 16/17/18
while still passing on PG 14/15. The matrix is light — one
Database CR per version, asserting Ready phase and secret
presence — so it stays cheap (~1 GB RAM, ~30-60s extra CI time)
while pinning behaviour across the supported version range.
Connecting as the built-in 'postgres' superuser bypasses the SET
ROLE check entirely (superusers can become any role unconditionally),
so the original matrix passed even on PG 16/17/18 where the bug
class is supposed to bite.

Bootstrap each PG instance with a non-superuser 'dbuo_admin' role
(LOGIN, CREATEDB, CREATEROLE, NOSUPERUSER, NOINHERIT) via a
ConfigMap-mounted /docker-entrypoint-initdb.d/init.sql. Repoint the
per-version connection-string Secrets at this admin. This mirrors
managed-PG providers (Scaleway managed RDB, self-hosted PG 16+
without RDS-style event triggers) where the admin is not a
superuser, so the operator's GRANT path is actually exercised.
…tBackend shape

PR #135 merged to main while this PR was open, replacing
spec.connectionStringSecretRef + bare spec.secretName with
spec.connectionString.kubernetes + spec.secretBackend.aws.
The WITH INHERIT/SET options on GRANT are PG 16+ syntax. PR #135
emitted them unconditionally, which broke the operator on PG 14
and 15 with 'syntax error at or near INHERIT' (42601), surfaced
by the new PG version matrix.

Detect server_version_num via current_setting() and only append
WITH INHERIT TRUE, SET TRUE on PG 16+. Pre-16 the default GRANT
is sufficient — bare role membership has always implied SET ROLE
on those versions, so CREATE/ALTER DATABASE OWNER works.
NOINHERIT prevented the admin from inheriting newuser's ownership
privileges, so COMMENT ON DATABASE and DROP DATABASE failed with
'must be owner of database' (42501) on every PG version after the
operator transferred ownership to the new user.

Real managed-PG providers (AWS rds_superuser, Scaleway
_rdb_superadmin, Aurora) all use INHERIT admin roles, so this
mirrors production more accurately and unblocks the matrix while
still keeping the admin non-superuser.
@opzkit-auto-merge opzkit-auto-merge Bot merged commit 84e199b into main May 7, 2026
7 checks passed
@opzkit-auto-merge opzkit-auto-merge Bot deleted the test/pg-version-matrix branch May 7, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants